﻿using Serilog;
using Serilog.Core;
using Serilog.Events;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Huioo.Learning.Logging.ConsoleAppWithSerilog
{
    /// <summary>
    /// 基于Serilog的日志组件，支持按名称配置日志路径
    /// </summary>
    public class LoggerComponent : IDisposable
    {
        private readonly ILogger _logger;
        private bool _disposed = false;
        private readonly string _logDirectory;

        /// <summary>
        /// 初始化日志组件
        /// </summary>
        /// <param name="name">用于配置日志路径的名称</param>
        /// <param name="baseDirectory">日志基础目录，默认为"Logs"</param>
        /// <param name="minimumLevel">最小日志级别，默认为Information</param>
        public LoggerComponent(string name, string baseDirectory = "Logs", LogEventLevel minimumLevel = LogEventLevel.Information)
        {
            if (string.IsNullOrWhiteSpace(name))
                throw new ArgumentException("日志名称不能为空或空白", nameof(name));

            // 确保基础目录存在
            if (!Directory.Exists(baseDirectory))
                Directory.CreateDirectory(baseDirectory);

            // 根据name配置日志路径
            _logDirectory = Path.Combine(baseDirectory, name);
            if (!Directory.Exists(_logDirectory))
                Directory.CreateDirectory(_logDirectory);

            string logFilePath = Path.Combine(_logDirectory, "log-.txt");

            // 配置Serilog
            var loggerConfiguration = new LoggerConfiguration()
                .MinimumLevel.Is(minimumLevel)
                .Enrich.FromLogContext()
                .WriteTo.Console(
                    outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
                .WriteTo.File(
                    path: logFilePath,
                    rollingInterval: RollingInterval.Day, // 按天滚动日志
                    retainedFileCountLimit: 30, // 保留30天的日志
                    outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff} [{Level:u3}] {Message:lj}{NewLine}{Exception}",
                    encoding: System.Text.Encoding.UTF8);

            _logger = loggerConfiguration.CreateLogger();

            // 设置全局日志器
            Log.Logger = _logger;
        }

        /// <summary>
        /// 获取日志文件保存目录
        /// </summary>
        public string LogDirectory => _logDirectory;

        /// <summary>
        /// 记录Debug级别日志
        /// </summary>
        public void Debug(string message, params object[] args) => _logger.Debug(message, args);

        /// <summary>
        /// 记录Information级别日志
        /// </summary>
        public void Information(string message, params object[] args) => _logger.Information(message, args);

        /// <summary>
        /// 记录Warning级别日志
        /// </summary>
        public void Warning(string message, params object[] args) => _logger.Warning(message, args);

        /// <summary>
        /// 记录Error级别日志
        /// </summary>
        public void Error(string message, params object[] args) => _logger.Error(message, args);

        /// <summary>
        /// 记录带有异常的Error级别日志
        /// </summary>
        public void Error(Exception ex, string message, params object[] args) => _logger.Error(ex, message, args);

        /// <summary>
        /// 记录Fatal级别日志
        /// </summary>
        public void Fatal(string message, params object[] args) => _logger.Fatal(message, args);

        /// <summary>
        /// 记录带有异常的Fatal级别日志
        /// </summary>
        public void Fatal(Exception ex, string message, params object[] args) => _logger.Fatal(ex, message, args);

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// 释放资源的实际实现
        /// </summary>
        protected virtual void Dispose(bool disposing)
        {
            if (_disposed)
                return;

            if (disposing)
            {
                // 释放托管资源
                ((Logger)_logger)?.Dispose();
                Log.CloseAndFlush();
            }

            _disposed = true;
        }

        /// <summary>
        /// 析构函数
        /// </summary>
        ~LoggerComponent()
        {
            Dispose(false);
        }
    }
}

